#region Using directives

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.ServiceProcess;
using System.Reflection;
using System.Management;
using System.Collections;
using System.Text.RegularExpressions;

#endregion

//============================================================================
//  File:    MainForm.cs
//
//  Summary: Implements the main UI and program for SQL2005 Service Manager
//
//----------------------------------------------------------------------------
//
// Copyright (C) sqldbatips.com.  All rights reserved.
//
//  THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//  PARTICULAR PURPOSE.
//============================================================================

namespace SQL2005_Service_Manager
{
	//main application UI
	public partial class MainForm : Form
	{

		#region Variables

		//constants
		const String APP_NAME = "SQL2005 Service Manager";
		const String START = "START";
		const String STOP = "STOP";
		const String PAUSE = "PAUSE";
		const String STARTUP_AUTO = "Auto";
		const String STARTUP_AUTOMATIC = "Automatic";
		const String STARTUP_MAN = "Manual";

		//globals
		private String servername = System.Environment.MachineName;
		private SQLServiceList sl = new SQLServiceList();
		private String currentinstance;
		private String currentservice;
        private String defaultinstance = System.Environment.MachineName;
		private int polling = 30;
		private String defaultservice = SQLServiceList.SQL_SERVER;
		private int ErrorCount = 0;

		//status
		private Boolean StartingUp = true;
		private Boolean RefreshingServices = false;
		private Boolean ChangingInstance = false;
		private Boolean OkToClose = false;

		#endregion

		#region Initialisation

		//constructor
		public MainForm()
		{
			InitializeComponent();
			InitializeBackgoundWorkers();
			InitializeTimer();
		}

		//form load event
		private void MainForm_Load(object sender, EventArgs e)
		{
			//don't show form
			this.Hide();

			//get the instances and services
			LoadUserSettings();
			PopulateComboBoxes();
            SetInstanceToolBarText();

			//enable timer for background refresh
			ServiceStatusTimer.Enabled = true;
			StartingUp = false;
		}

		//set worker properties and event handlers
		private void InitializeBackgoundWorkers()
		{
			//used to poll service status
			ServiceStatusWorker.WorkerReportsProgress = false;
			ServiceStatusWorker.WorkerSupportsCancellation = false;
			ServiceStatusWorker.DoWork += new DoWorkEventHandler(ServiceStatusWorker_DoWork);
			ServiceStatusWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ServiceStatusWorker_RunWorkerCompleted);

			//used to perform service actions
			ServiceActionWorker.WorkerReportsProgress = false;
			ServiceActionWorker.WorkerSupportsCancellation = false;
			ServiceActionWorker.DoWork += new DoWorkEventHandler(ServiceActionWorker_DoWork);
			ServiceActionWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ServiceActionWorker_RunWorkerCompleted);
		}

		// set service polling interval - default 30 seconds - but don't enable yet
		private void InitializeTimer()
		{
			ServiceStatusTimer.Interval = (polling * 1000);
			ServiceStatusTimer.Enabled = false;
		}

		//Load user settings
		private void LoadUserSettings()
		{
            if (!String.IsNullOrEmpty(Properties.Settings.Default.DefaultInstance))
            {
                defaultinstance = Properties.Settings.Default.DefaultInstance;
            }
			defaultservice = Properties.Settings.Default.DefaultService;
			polling = Properties.Settings.Default.PollingInterval;
		}


		#endregion

		#region BackgroundWorker event handlers

		// use a background thread to get the service state
		private void ServiceStatusWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
		{
			BackgroundRefreshService();
		}

		// use a background thread to perform service acction
		private void ServiceActionWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
		{
			//reset ErrorCount
			ErrorCount = 0;
			//get the service action argument
			String action = e.Argument.ToString();
			//do the work and capature error if any
			e.Result = ServiceAction(currentinstance, currentservice, action);
		}

		// when polling finished update all
		private void ServiceStatusWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
		{
			UpdateNotifyIcon();
		}

		// when action complete update status
		private void ServiceActionWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
		{
			ServiceActionProgressBar.Enabled = false;
			ServiceActionProgressBar.Visible = false;

			//this event seems to fire twice following an error so the ErrorCount is used to avoid displaying the error twice
			if (e.Result !=null && ErrorCount == 0)
			{
				ErrorCount += 1;
				ShowError((Exception)e.Result);
			}
			EnableAllControls(true);
			UpdateNotifyIcon();
		}

		// when polling interval is reached poll currentservice       
		private void ServiceStatusTimer_Tick(object sender, EventArgs e)
		{
			// only bother if there is a service to poll
            if (currentservice != null && StartingUp == false && ChangingInstance == false && ServiceStatusWorker.IsBusy == false)
				ServiceStatusWorker.RunWorkerAsync();
		}

		#endregion

		#region ServiceMethods

		//refresh current service
		private void BackgroundRefreshService()
		{ 
			if(currentservice != null)
			{
				SC.ServiceName = currentservice;
				SC.Refresh();
			}
		}

		//perform a service action
		private Exception ServiceAction(string currentinstance, string currentservice, string action)
		{
			if (currentservice != null && currentinstance != null && action != null)
			{
				//service status
				SC.ServiceName = currentservice;
				ServiceControllerStatus state = SC.Status;

				try
				{
					//perform service action
					switch (action)
					{
						case START:
							if (state == ServiceControllerStatus.Stopped)
							{
								SC.Start();
								SC.WaitForStatus(ServiceControllerStatus.Running);
								break;
							}
							if (SC.CanPauseAndContinue == true && state == ServiceControllerStatus.Paused)
							{
								SC.Continue();
								SC.WaitForStatus(ServiceControllerStatus.Running);
								break;
							}
							break;

						case STOP:
							if (state == ServiceControllerStatus.Running)
							{
								SC.Stop();
								SC.WaitForStatus(ServiceControllerStatus.Stopped);
							}
							break;

						case PAUSE:
							if (SC.CanPauseAndContinue == true && state == ServiceControllerStatus.Running)
							{
								SC.Pause();
								SC.WaitForStatus(ServiceControllerStatus.Paused);
							}
							break;
						default:
							break;
					}
				}
				catch (Exception ex)
				{
					return ex;
				}

				SC.Refresh();
				return null;
			}
			return null;
		}

		//checks if service startup is set to Automatic
		private bool ServiceStartupIsAutomatic(String servicename)
		{
			String startuptype;
			String path = "Win32_Service.Name='" + servicename + "'";
			ManagementPath p = new ManagementPath(path);
			ManagementObject ManagementObj = new ManagementObject(p);
			try
			{
				startuptype = ManagementObj["StartMode"].ToString();

				if (startuptype == STARTUP_AUTO)
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			catch (ManagementException ex)
			{
				ShowError(ex);
				return false;
			}
			catch (Exception ex)
			{
				ShowError(ex);
				return false;
			}
			finally
			{
				ManagementObj.Dispose();
				ManagementObj = null;
			}
		}

		//set service startup type
		private void SetServiceStartupType(String servicename,String startuptype)
		{
			ServiceStatusTimer.Enabled = false;
			String path = "Win32_Service.Name='" + servicename + "'";
			ManagementPath p = new ManagementPath(path);
			ManagementObject ManagementObj = new ManagementObject(p);

			try
			{
				object[] parameters = new object[1];
				parameters[0] = startuptype;
				ManagementObj.InvokeMethod("ChangeStartMode", parameters);
			}
			catch (ManagementException ex)
			{
				ShowError(ex);
			}
			catch (Exception ex)
			{
				ShowError(ex);
			}
			finally
			{
				ManagementObj.Dispose();
				ManagementObj = null;
				ServiceStatusTimer.Enabled = true;
			}
		}


		#endregion 

		#region UIMethods

        //sets instance menu text
        private void SetInstanceToolBarText()
        {
            //clear any existing items
            CurrentInstancetoolStripMenuItem.DropDownItems.Clear();

            //get the comma delimited list of instances
            string instancelist = sl.InstanceList();
            if (null != instancelist)
            {
                int i = 0;
                int index = 0;
                int numinstances = (CountStrings(instancelist, ",") + 1);
                string[] instarray = instancelist.Split(",".ToCharArray());
                
                // add a menu item and event handlder for each instance
                foreach (string s in instarray)
                {
                    if (s == defaultinstance)
                    {
                        index = i;
                    }
                    CurrentInstancetoolStripMenuItem.DropDownItems.Add(new ToolStripMenuItem(s, null, new EventHandler(instanceToolStripMenuItem_Click)));
                    i += 1;
                }
                // select the first in the list
                ToolStripMenuItem it = (ToolStripMenuItem)CurrentInstancetoolStripMenuItem.DropDownItems[index];
                it.Checked = true;
            }
        }

        // check the relavent instance item when changed via the instance dropdown
        private void SetInstanceToolBarCheck()
        {
            ClearSelectedInstanceItem();
            foreach (ToolStripMenuItem it in CurrentInstancetoolStripMenuItem.DropDownItems)
            {
                if (it.Text == currentinstance)
                {
                    it.Checked = true;
                    break;
                }
            }
        }

        //clear check mark from instance menu items
        private void ClearSelectedInstanceItem()
        {
            foreach (ToolStripMenuItem it in CurrentInstancetoolStripMenuItem.DropDownItems)
            {
                it.Checked = false;
            }
        }

		//sets UI control state - used to disable all controls during service action
		private void EnableAllControls(bool enable)
		{
			btnPause.Enabled = enable;
			btnStop.Enabled = enable;
			btnStart.Enabled = enable;
			btnRefresh.Enabled = enable;
			cmbInstance.Enabled = enable;
			cmbService.Enabled = enable;
            serviceStopToolStripMenuItem.Enabled = enable;
            serviceStartToolStripMenuItem.Enabled = enable;
            servicePauseToolStripMenuItem.Enabled = enable;
            currentServiceToolStripMenuItem.Enabled = enable;
            CurrentInstancetoolStripMenuItem.Enabled = enable;
		}

		//populates instances and services
		private void PopulateComboBoxes()
		{
			//clear items
			cmbInstance.DataSource = null;
			cmbService.DataSource = null;

			//Instances
			cmbInstance.DataSource = sl.Instances();
			cmbInstance.DisplayMember = "InstanceName";
			cmbInstance.ValueMember = "InstanceName";

			//get services for instance
			if (cmbInstance.Items.Count > 0)
			{
                    if (defaultinstance != null)
                    {
                        int index = cmbInstance.FindStringExact(defaultinstance);
                        if (index > -1)
                        {
                            cmbInstance.SelectedIndex = index;
                        }
                        else
                        {
                            cmbInstance.SelectedIndex = 0;
                        }
                    }
					currentinstance = cmbInstance.SelectedValue.ToString();

					//Services
					cmbService.DataSource = sl.Services(currentinstance);
					cmbService.DisplayMember = "DisplayName";
					cmbService.ValueMember = "ServiceName";
					if (cmbService.Items.Count > 0)
					{

						if (defaultservice != null)
						{
							int defaultindex = cmbService.FindStringExact(defaultservice);
							if (defaultindex > -1)
							{
								cmbService.SelectedIndex = defaultindex;
							}
							else
							{
								cmbService.SelectedIndex = 0;
							}
						}
						currentservice = cmbService.SelectedValue.ToString();
					}
			}

			//enable buttons if there are services
			if (currentinstance != null && currentservice != null)
			{
				EnableAllControls(true);
				UpdateNotifyIcon();
				SetToolBarMenu();
			}
			else
			{
				EnableAllControls(false);
			}
		}

		//sets the available toolbar options from the context menu
		private void SetToolBarMenu()
		{
			//disable all
			analysisServicesToolStripMenuItem.Enabled = false;
			fullTextSearchToolStripMenuItem.Enabled = false;
			mSDTCToolStripMenuItem.Enabled = false;
			reportingServicesToolStripMenuItem.Enabled = false;
			sQLAgentToolStripMenuItem.Enabled = false;
			sQLServerToolStripMenuItem.Enabled = false;
            sSISServiceToolStripMenuItem.Enabled = false;
            sSIS2008ServiceToolStripMenuItem.Enabled = false;
            sQLBrowserToolStripMenuItem.Enabled = false;

			if (cmbService.Items.Count > 0)
			{
				for (int i = 0; i < cmbService.Items.Count;i++ )
				{
					DataRowView dr = (DataRowView)cmbService.Items[i];
					String servicename = dr[2].ToString();
					switch (servicename)
					{
						case SQLServiceList.ANALYSIS:
							analysisServicesToolStripMenuItem.Enabled = true;
							break;
						case SQLServiceList.FTSEARCH:
							fullTextSearchToolStripMenuItem.Enabled = true;
							break;
						case SQLServiceList.MSDTC:
							mSDTCToolStripMenuItem.Enabled = true;
							break;
						case SQLServiceList.REPORT:
							reportingServicesToolStripMenuItem.Enabled = true;
							break;
						case SQLServiceList.SQL_AGENT:
							sQLAgentToolStripMenuItem.Enabled = true;
							break;
						case SQLServiceList.SQL_SERVER:
							sQLServerToolStripMenuItem.Enabled = true;
							break;
                        case SQLServiceList.SSIS:
                            sSISServiceToolStripMenuItem.Enabled = true;
                            break;
                        case SQLServiceList.SSIS2008:
                            sSIS2008ServiceToolStripMenuItem.Enabled = true;
                            break;
                        case SQLServiceList.BROWSER:
                            sQLBrowserToolStripMenuItem.Enabled = true;
                            break;
						default:
							break;
					}
				}
			
			}
		}

		//generic error message display
		internal static void ShowError(Exception ex)
		{
			String errorMessage;

			errorMessage = ex.Message;
			while (ex.InnerException != null)
			{
				errorMessage += Environment.NewLine + ex.InnerException.Message;
				ex = ex.InnerException;
			}

			MessageBox.Show(errorMessage, APP_NAME + @" - Error",
				MessageBoxButtons.OK, MessageBoxIcon.Error,
				MessageBoxDefaultButton.Button1);
		}

		// update status icon
		private void UpdateStatusIcon()
		{
			if (currentservice != null && (this.Visible == true || StartingUp == true))
			{
				if (pbStatus.Image != null)
					pbStatus.Image.Dispose();

				SC.ServiceName = currentservice;
				SC.Refresh();
				ServiceControllerStatus state = SC.Status;

				try
				{
					switch (state)
					{
						case ServiceControllerStatus.Running:
							pbStatus.Image = global::SQL2005_Service_Manager.Properties.Resources.run;
							svcStatusLabel.Text = "Service Running";
							break;
						case ServiceControllerStatus.Stopped:
							pbStatus.Image = global::SQL2005_Service_Manager.Properties.Resources.stop;
							svcStatusLabel.Text = "Service Stopped";
							break;
						case ServiceControllerStatus.Paused:
							pbStatus.Image = global::SQL2005_Service_Manager.Properties.Resources.pause;
							svcStatusLabel.Text = "Service Paused";
							break;
						default:
							pbStatus.Image = global::SQL2005_Service_Manager.Properties.Resources.unknown;
							svcStatusLabel.Text = "";
							break;
					}

					//UI service control buttons
					UpdateButtons(state);
					//service autostart checkbox
					chkAutoStart.Checked = (ServiceStartupIsAutomatic(currentservice) == true) ? true : false;
				}
				catch
				{ }
			}
		}

		//update buttons dependent on service state
		private void UpdateButtons(ServiceControllerStatus state)
		{
			switch (state)
			{
				case ServiceControllerStatus.Running:
					btnPause.Enabled = (SC.CanPauseAndContinue == true)?true:false;
					btnStop.Enabled = true;
					btnStart.Enabled = false;
					break;
				case ServiceControllerStatus.Stopped:
					btnPause.Enabled = false;
					btnStop.Enabled = false;
					btnStart.Enabled = true;
					break;
				case ServiceControllerStatus.Paused:
					btnPause.Enabled =  false;
					btnStop.Enabled = false;
					btnStart.Enabled = true;
					break;
				default:
					btnPause.Enabled =  false;
					btnStop.Enabled = false;
					btnStart.Enabled = false;
					break;
			}
		}

		// update notify icon and text
		private void UpdateNotifyIcon()
		{
			if (currentservice != null)
			{

				//service status
				SC.ServiceName = currentservice;
				ServiceControllerStatus state = SC.Status;

				//get service friendly display name
				String friendlyname = sl.ServiceToDisplay(currentservice);
				String tooltipmsg = SC.Status + " - \\\\" + currentinstance + " - " + friendlyname;

				//context menu
				currentServiceToolStripMenuItem.DropDown.Enabled = true;
				SetContextMenuText(currentservice);

				//set icon based on service state
				switch (friendlyname)
				{

					case SQLServiceList.SQL_SERVER:
					case SQLServiceList.MSDTC:
					case SQLServiceList.REPORT:
                    case SQLServiceList.SSIS:
                    case SQLServiceList.SSIS2008:
                    case SQLServiceList.BROWSER:
						switch (state)
						{
							case ServiceControllerStatus.Running:
								notifyIcon.Icon = global::SQL2005_Service_Manager.Properties.Resources._16_1_001;
								break;
							case ServiceControllerStatus.Paused:
								notifyIcon.Icon = global::SQL2005_Service_Manager.Properties.Resources._16_1_003;
								break;
							case ServiceControllerStatus.Stopped:
								notifyIcon.Icon = global::SQL2005_Service_Manager.Properties.Resources._16_1_002;
								break;
							default:
								notifyIcon.Icon = global::SQL2005_Service_Manager.Properties.Resources._16_1_005;
								break;
						}
						break;

					case SQLServiceList.SQL_AGENT:
						switch (state)
						{
							case ServiceControllerStatus.Running:
								notifyIcon.Icon = global::SQL2005_Service_Manager.Properties.Resources._16_1_012;
								break;
							case ServiceControllerStatus.Paused:
								notifyIcon.Icon = global::SQL2005_Service_Manager.Properties.Resources._16_1_011;
								break;
							case ServiceControllerStatus.Stopped:
								notifyIcon.Icon = global::SQL2005_Service_Manager.Properties.Resources._16_1_010;
								break;
							default:
								notifyIcon.Icon = global::SQL2005_Service_Manager.Properties.Resources._16_1_005;
								break;
						}
						break;

					case SQLServiceList.ANALYSIS:
						switch (state)
						{
							case ServiceControllerStatus.Running:
								notifyIcon.Icon = global::SQL2005_Service_Manager.Properties.Resources._16_1_050;
								break;
							case ServiceControllerStatus.Paused:
								notifyIcon.Icon = global::SQL2005_Service_Manager.Properties.Resources._16_1_049;
								break;
							case ServiceControllerStatus.Stopped:
								notifyIcon.Icon = global::SQL2005_Service_Manager.Properties.Resources._16_1_048;
								break;
							default:
								notifyIcon.Icon = global::SQL2005_Service_Manager.Properties.Resources._16_1_051;
								break;
						}
						break;

					case SQLServiceList.FTSEARCH:
						switch (state)
						{
							case ServiceControllerStatus.Running:
								notifyIcon.Icon = global::SQL2005_Service_Manager.Properties.Resources._16_1_042;
								break;
							case ServiceControllerStatus.Paused:
								notifyIcon.Icon = global::SQL2005_Service_Manager.Properties.Resources._16_1_041;
								break;
							case ServiceControllerStatus.Stopped:
								notifyIcon.Icon = global::SQL2005_Service_Manager.Properties.Resources._16_1_040;
								break;
							default:
								notifyIcon.Icon = global::SQL2005_Service_Manager.Properties.Resources._16_1_043;
								break;
						}
						break;

					default:
						// default to sql unknown icon - as good as any
						notifyIcon.Icon = global::SQL2005_Service_Manager.Properties.Resources._16_1_005;
						break;
				}

				//set tray icon tooltip
				notifyIcon.Text = tooltipmsg;

				//if visible then update main UI also
				if (this.Visible == true || StartingUp == true)
				{
					UpdateStatusIcon();
				}
			}
		}

		// set the context menu items text and state to reflect the service state
		private void SetContextMenuText(string currentservice)
		{

			String friendlyservicename = sl.ServiceToDisplay(currentservice);
			ServiceControllerStatus state = SC.Status;

			switch (friendlyservicename)
			{
				case SQLServiceList.ANALYSIS:
					analysisServicesToolStripMenuItem.Checked = true;
					mSDTCToolStripMenuItem.Checked = false;
					fullTextSearchToolStripMenuItem.Checked = false;
					reportingServicesToolStripMenuItem.Checked = false;
					sQLAgentToolStripMenuItem.Checked = false;
					sQLServerToolStripMenuItem.Checked = false;
                    sSISServiceToolStripMenuItem.Checked = false;
                    sQLBrowserToolStripMenuItem.Checked = false;
                    sSIS2008ServiceToolStripMenuItem.Checked = false;
					break;
				case SQLServiceList.MSDTC:
					analysisServicesToolStripMenuItem.Checked = false;
					mSDTCToolStripMenuItem.Checked = true;
					fullTextSearchToolStripMenuItem.Checked = false;
					reportingServicesToolStripMenuItem.Checked = false;
					sQLAgentToolStripMenuItem.Checked = false;
					sQLServerToolStripMenuItem.Checked = false;
                    sSISServiceToolStripMenuItem.Checked = false;
                    sQLBrowserToolStripMenuItem.Checked = false;
                    sSIS2008ServiceToolStripMenuItem.Checked = false;
					break;
				case SQLServiceList.REPORT:
					analysisServicesToolStripMenuItem.Checked = false;
					mSDTCToolStripMenuItem.Checked = false;
					fullTextSearchToolStripMenuItem.Checked = false;
					reportingServicesToolStripMenuItem.Checked = true;
					sQLAgentToolStripMenuItem.Checked = false;
					sQLServerToolStripMenuItem.Checked = false;
                    sSISServiceToolStripMenuItem.Checked = false;
                    sQLBrowserToolStripMenuItem.Checked = false;
                    sSIS2008ServiceToolStripMenuItem.Checked = false;
					break;
				case SQLServiceList.FTSEARCH:
					analysisServicesToolStripMenuItem.Checked = false;
					mSDTCToolStripMenuItem.Checked = false;
					fullTextSearchToolStripMenuItem.Checked = true;
					reportingServicesToolStripMenuItem.Checked = false;
					sQLAgentToolStripMenuItem.Checked = false;
					sQLServerToolStripMenuItem.Checked = false;
                    sSISServiceToolStripMenuItem.Checked = false;
                    sQLBrowserToolStripMenuItem.Checked = false;
                    sSIS2008ServiceToolStripMenuItem.Checked = false;
					break;
				case SQLServiceList.SQL_AGENT:
					analysisServicesToolStripMenuItem.Checked = false;
					mSDTCToolStripMenuItem.Checked = false;
					fullTextSearchToolStripMenuItem.Checked = false;
					reportingServicesToolStripMenuItem.Checked = false;
					sQLAgentToolStripMenuItem.Checked = true;
					sQLServerToolStripMenuItem.Checked = false;
                    sSISServiceToolStripMenuItem.Checked = false;
                    sQLBrowserToolStripMenuItem.Checked = false;
                    sSIS2008ServiceToolStripMenuItem.Checked = false;
					break;
				case SQLServiceList.SQL_SERVER:
					analysisServicesToolStripMenuItem.Checked = false;
					mSDTCToolStripMenuItem.Checked = false;
					fullTextSearchToolStripMenuItem.Checked = false;
					reportingServicesToolStripMenuItem.Checked = false;
					sQLAgentToolStripMenuItem.Checked = false;
					sQLServerToolStripMenuItem.Checked = true;
                    sSISServiceToolStripMenuItem.Checked = false;
                    sQLBrowserToolStripMenuItem.Checked = false;
                    sSIS2008ServiceToolStripMenuItem.Checked = false;
					break;
                case SQLServiceList.SSIS:
                    analysisServicesToolStripMenuItem.Checked = false;
                    mSDTCToolStripMenuItem.Checked = false;
                    fullTextSearchToolStripMenuItem.Checked = false;
                    reportingServicesToolStripMenuItem.Checked = false;
                    sQLAgentToolStripMenuItem.Checked = false;
                    sQLServerToolStripMenuItem.Checked = false;
                    sSISServiceToolStripMenuItem.Checked = true;
                    sQLBrowserToolStripMenuItem.Checked = false;
                    sSIS2008ServiceToolStripMenuItem.Checked = false;
                    break;
                case SQLServiceList.SSIS2008:
                    analysisServicesToolStripMenuItem.Checked = false;
                    mSDTCToolStripMenuItem.Checked = false;
                    fullTextSearchToolStripMenuItem.Checked = false;
                    reportingServicesToolStripMenuItem.Checked = false;
                    sQLAgentToolStripMenuItem.Checked = false;
                    sQLServerToolStripMenuItem.Checked = false;
                    sSISServiceToolStripMenuItem.Checked = false;
                    sQLBrowserToolStripMenuItem.Checked = false;
                    sSIS2008ServiceToolStripMenuItem.Checked = true;
                    break;
                case SQLServiceList.BROWSER:
                    analysisServicesToolStripMenuItem.Checked = false;
                    mSDTCToolStripMenuItem.Checked = false;
                    fullTextSearchToolStripMenuItem.Checked = false;
                    reportingServicesToolStripMenuItem.Checked = false;
                    sQLAgentToolStripMenuItem.Checked = false;
                    sQLServerToolStripMenuItem.Checked = false;
                    sSISServiceToolStripMenuItem.Checked = false;
                    sQLBrowserToolStripMenuItem.Checked = true;
                    sSIS2008ServiceToolStripMenuItem.Checked = false;
                    break;
				default:
					break;
			}

			currentServiceToolStripMenuItem.Text = "Service on \\\\" + currentinstance;
			serviceStartToolStripMenuItem.Text = friendlyservicename + " - Start";
			serviceStopToolStripMenuItem.Text = friendlyservicename + " - Stop";
			servicePauseToolStripMenuItem.Text = friendlyservicename + " - Pause";

			if (state == ServiceControllerStatus.Running)
			{
				serviceStartToolStripMenuItem.Enabled = false;
				if (SC.CanPauseAndContinue == true)
				{
					servicePauseToolStripMenuItem.Enabled = true;
				}
				else
				{
					servicePauseToolStripMenuItem.Enabled = false;
				}
				serviceStopToolStripMenuItem.Enabled = true;
			}
			else if (state == ServiceControllerStatus.Stopped)
			{
				serviceStartToolStripMenuItem.Enabled = true;
				servicePauseToolStripMenuItem.Enabled = false;
				serviceStopToolStripMenuItem.Enabled = false;
			}
			else if (state == ServiceControllerStatus.Paused)
			{
				serviceStartToolStripMenuItem.Enabled = true;
				servicePauseToolStripMenuItem.Enabled = false;
				serviceStopToolStripMenuItem.Enabled = false;
			}
			else
			{
				serviceStartToolStripMenuItem.Enabled = false;
				servicePauseToolStripMenuItem.Enabled = false;
				serviceStopToolStripMenuItem.Enabled = false;
			}

		}

        // count strings in strings
        private static int CountStrings(string str, string regexStr)
        {
            Regex regex = new Regex(regexStr);
            return regex.Matches(str).Count;
        }

		#endregion

		#region UI Event handlers

		//refresh services
		private void btnRefresh_Click(object sender, EventArgs e)
		{
			ServiceStatusTimer.Enabled = false;
			RefreshingServices = true;

			//save currently selected instance and service
			int savedInstanceindex = cmbInstance.FindStringExact(currentinstance);
			int savedServiceindex = cmbService.FindStringExact(sl.ServiceToDisplay(currentservice));

			//refresh services and instances
			PopulateComboBoxes();
			RefreshingServices = false;

			//reinstate saved selections
			cmbInstance.SelectedIndex = savedInstanceindex;
			cmbService.SelectedIndex = savedServiceindex;

			ServiceStatusTimer.Enabled = true;
			Application.DoEvents();
		}

		//start or continue service
		private void btnStart_Click(object sender, EventArgs e)
		{
			//display progress
			if (this.Visible == true)
			{
				ServiceActionProgressBar.Enabled = true;
				ServiceActionProgressBar.Visible = true;
			}
			svcStatusLabel.Text = "Service Starting";
			EnableAllControls(false);
			ServiceActionWorker.RunWorkerAsync(START);
			Application.DoEvents();
		}

		//stop service
		private void btnStop_Click(object sender, EventArgs e)
		{
			//display progress
			if (this.Visible == true)
			{
				ServiceActionProgressBar.Enabled = true;
				ServiceActionProgressBar.Visible = true;
			}
			svcStatusLabel.Text = "Service Stopping";
			EnableAllControls(false);
			ServiceActionWorker.RunWorkerAsync(STOP);
			Application.DoEvents();
		}

		//pause service
		private void btnPause_Click(object sender, EventArgs e)
		{
			//display progress
			if (this.Visible == true)
			{
				ServiceActionProgressBar.Enabled = true;
				ServiceActionProgressBar.Visible = true;
			}
			svcStatusLabel.Text = "Service Pausing";
			EnableAllControls(false);
			ServiceActionWorker.RunWorkerAsync(PAUSE);
			Application.DoEvents();
		}

		//change instance
		private void cmbInstance_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (StartingUp == false && RefreshingServices == false)
			{
				String selectedinstance = cmbInstance.SelectedValue.ToString();
				if (selectedinstance != currentinstance)
				{
					ChangingInstance = true;
					cmbService.DataSource = null;
					cmbService.Items.Clear();
					cmbService.DataSource = sl.Services(selectedinstance);
					cmbService.DisplayMember = "DisplayName";
					cmbService.ValueMember = "ServiceName";
					if (cmbService.Items.Count > 0)
					{
						if (defaultservice != null)
						{
							int defaultindex = cmbService.FindStringExact(defaultservice);
							if (defaultindex > -1)
							{
								cmbService.SelectedIndex = defaultindex;
							}
							else
							{
								cmbService.SelectedIndex = 0;
							}
						}
						currentservice = cmbService.SelectedValue.ToString();
					}
					currentinstance = selectedinstance;
                    SetInstanceToolBarCheck();
					ChangingInstance = false;
					SetToolBarMenu();
					UpdateNotifyIcon();
				}
			}
		}

		//change service
		private void cmbService_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (StartingUp == false && RefreshingServices == false && ChangingInstance == false)
			{
				String selectedservice = cmbService.SelectedValue.ToString();
				if (selectedservice != null && selectedservice != currentservice)
				{
					currentservice = selectedservice;
					UpdateNotifyIcon();
				}
			}
		}

		//capture form closing event and only close if the user has explicitly selected exit from the context menu or windows is shutting down
		private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
		{
			if (e.CloseReason == CloseReason.WindowsShutDown)
				OkToClose = true;

			if (OkToClose == false)
			{
				e.Cancel = true; //don't close 
				this.Hide();
			}
		}

		//context menu Open
		private void openMenuItem_Click(object sender, EventArgs e)
		{
			if (FormWindowState.Minimized == WindowState && this.Visible == true)
			{
				WindowState = FormWindowState.Normal;
			}
			else
			{
				this.Show();
				WindowState = FormWindowState.Normal;
			}
			//update images
			UpdateNotifyIcon();
			Application.DoEvents();
		}

		//context menu exit
		private void exitToolStripMenuItem_Click(object sender, EventArgs e)
		{
			try
			{
				OkToClose = true;
				ServiceStatusTimer.Enabled = false;
				ServiceStatusWorker.Dispose();
				ServiceActionWorker.Dispose();
				this.Close();
			}
			catch
			{ }
			finally
			{
				Application.Exit();
			}

		}

		//context menu Options
		private void optionsToolStripMenuItem_Click(object sender, EventArgs e)
		{
			OptionForm oform = new OptionForm();
			oform.DefaultService = defaultservice;
			oform.Pollinginterval = polling;
            oform.DefaultInstance = defaultinstance;
            oform.ServiceList = sl;
			DialogResult res = oform.ShowDialog(this);
			oform.Dispose();
			if (res == DialogResult.OK)
			{
				LoadUserSettings();
			}
			Application.DoEvents();
		}

		//context menu service start
		private void serviceStartToolStripMenuItem_Click(object sender, EventArgs e)
		{
			this.btnStart_Click(sender, e);
		}

		//context menu service pause
		private void servicePauseToolStripMenuItem_Click(object sender, EventArgs e)
		{
			this.btnPause_Click(sender, e);
		}

		//context menu service stop
		private void serviceStopToolStripMenuItem_Click(object sender, EventArgs e)
		{
			this.btnStop_Click(sender, e);
		}

		//show About dialog
		private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
		{
			AboutForm aform = new AboutForm();
			aform.ShowDialog(this);
			aform.Dispose();
		}

		//click on analysisServicesToolStripMenuItem
		private void analysisServicesToolStripMenuItem_Click(object sender, EventArgs e)
		{
			analysisServicesToolStripMenuItem.Checked = true;
			cmbService.SelectedIndex = cmbService.FindStringExact(analysisServicesToolStripMenuItem.Text);
		}

		//click on fullTextSearchToolStripMenuItem
		private void fullTextSearchToolStripMenuItem_Click(object sender, EventArgs e)
		{
			fullTextSearchToolStripMenuItem.Checked = true;
			cmbService.SelectedIndex = cmbService.FindStringExact(fullTextSearchToolStripMenuItem.Text);
		}

		//click on mSDTCToolStripMenuItem
		private void mSDTCToolStripMenuItem_Click(object sender, EventArgs e)
		{
			mSDTCToolStripMenuItem.Checked = true;
			cmbService.SelectedIndex = cmbService.FindStringExact(mSDTCToolStripMenuItem.Text);
		}

		//click on reportingServicesToolStripMenuItem
		private void reportingServicesToolStripMenuItem_Click(object sender, EventArgs e)
		{
			reportingServicesToolStripMenuItem.Checked = true;
			cmbService.SelectedIndex = cmbService.FindStringExact(reportingServicesToolStripMenuItem.Text);
		}

		//click on sQLAgentToolStripMenuItem
		private void sQLAgentToolStripMenuItem_Click(object sender, EventArgs e)
		{
			sQLAgentToolStripMenuItem.Checked = true;
			cmbService.SelectedIndex = cmbService.FindStringExact(sQLAgentToolStripMenuItem.Text);
		}

		//click on sQLServerToolStripMenuItem
		private void sQLServerToolStripMenuItem_Click(object sender, EventArgs e)
		{
			sQLServerToolStripMenuItem.Checked = true;
			cmbService.SelectedIndex = cmbService.FindStringExact(sQLServerToolStripMenuItem.Text);
		}

        //click on sSISServiceToolStripMenuItem
        private void sSISServiceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            sSISServiceToolStripMenuItem.Checked = true;
            cmbService.SelectedIndex = cmbService.FindStringExact(sSISServiceToolStripMenuItem.Text);
        }

        //click on sSIS2008ServiceToolStripMenuItem
        private void sSIS2008ServiceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            sSIS2008ServiceToolStripMenuItem.Checked = true;
            cmbService.SelectedIndex = cmbService.FindStringExact(sSIS2008ServiceToolStripMenuItem.Text);
        }

        //click on sQLBrowserToolStripMenuItem
        private void sQLBrowserToolStripMenuItem_Click(object sender, EventArgs e)
        {
            sQLBrowserToolStripMenuItem.Checked = true;
            cmbService.SelectedIndex = cmbService.FindStringExact(sQLBrowserToolStripMenuItem.Text);
        }

		//handles autostart checking
		private void chkAutoStart_CheckedChanged(object sender, EventArgs e)
		{
			if (StartingUp == false && ChangingInstance == false)
			{
				if (chkAutoStart.CheckState == CheckState.Checked)
				{
					SetServiceStartupType(currentservice, STARTUP_AUTOMATIC);
				}
				else
				{
					SetServiceStartupType(currentservice, STARTUP_MAN);
				}
			}
		}

        //click on instanceToolStripMenuItem
        private void instanceToolStripMenuItem_Click(object sender, EventArgs e)
        {
                ClearSelectedInstanceItem();
                ToolStripMenuItem item = (ToolStripMenuItem)sender;
                item.Checked = true;
                cmbInstance.SelectedIndex = cmbInstance.FindStringExact(item.Text);
        }


		#endregion




	}
}